package org.usp.poli.bipt.server;

import java.util.ArrayList;
import java.util.List;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.datanucleus.store.exceptions.NoTableManagedException;
import org.usp.poli.bipt.server.DarwinCoreBasic;
import org.usp.poli.bipt.client.GreetingService;
import org.usp.poli.bipt.shared.FieldVerifier;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import org.usp.poli.bipt.server.PMF;
import org.usp.poli.bipt.server.bd.BasicMetadataTypesBD;
import org.usp.poli.bipt.server.bd.GeneralKeywordsBD;
import org.usp.poli.bipt.server.bd.GeographicCoverageBD;
import org.usp.poli.bipt.server.bd.IPRightBD;
import org.usp.poli.bipt.server.bd.LowestCommonTaxBD;
import org.usp.poli.bipt.server.bd.MetaDataBD;
import org.usp.poli.bipt.server.bd.MethodsBD;
import org.usp.poli.bipt.server.bd.ResearchProjectBD;
import org.usp.poli.bipt.server.bd.ResourceOriginatorBD;
import org.usp.poli.bipt.server.bd.TaxonomicCoverageBD;
import org.usp.poli.bipt.server.bd.TemporalCoverageBD;
import org.usp.poli.bipt.client.metadata.*;


/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {
	
	public String greetServer(String input) throws IllegalArgumentException {
		// Verify that the input is valid. 
		if (!FieldVerifier.isValidName(input)) {
			// If the input is not valid, throw an IllegalArgumentException back to
			// the client.
			throw new IllegalArgumentException(
					"Name must be at least 4 characters long");
		}

		String serverInfo = getServletContext().getServerInfo();
		String userAgent = getThreadLocalRequest().getHeader("User-Agent");
		return "Hello, " + input + "!<br><br>I am running " + serverInfo
				+ ".<br><br>It looks like you are using:<br>" + userAgent;
	}
	
	public String setDarwinCore(String input) throws IllegalArgumentException {
		try {
			PersistenceManager pm = PMF.get().getPersistenceManager();

			DarwinCoreBasic data = new DarwinCoreBasic();
            pm.makePersistent(data);
            return null;
        } finally {
        	
            //pm.close();
        }
	}

	public String setBasicMetaData(MetaData data)
			throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();

		MetaDataBD metaDataBD = parseMetaDataBD(data);
		
		
		Key key = KeyFactory.createKey(MetaDataBD.class.getSimpleName(), metaDataBD.getContactEmail());
		metaDataBD.setKeyMetaData(key);
		
        try {
            pm.makePersistent(metaDataBD);
        } finally {
            pm.close();
        }
		return KeyFactory.keyToString(key);
	}

	private MetaDataBD parseMetaDataBD(MetaData data) {
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD.setContactEmail(data.getContactEmail());
		metaDataBD.setContactName(data.getContactName());
		metaDataBD.setTitle(data.getTitle());
		metaDataBD.setUpdateLogo(data.getUpdateLogo());
		metaDataBD.setDescription(data.getDescription());
		return metaDataBD;
	}
	
	private MetaData parseMetaData(MetaDataBD data) {
		MetaData metaData = new MetaData();
		metaData.setKey(data.getKeyMetaData().toString());
		metaData.setContactEmail(data.getContactEmail());
		metaData.setContactName(data.getContactName());
		metaData.setTitle(data.getTitle());
		metaData.setUpdateLogo(data.getUpdateLogo());
		metaData.setDescription(data.getDescription());
		return metaData;
	}

	public String setBasicMetadataTypes(BasicMetadataTypes data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		BasicMetadataTypesBD basicMetadataTypes = new BasicMetadataTypesBD();
		basicMetadataTypes.setDescription(data.getDescription());
		metaDataBD.setBasicMetadataTypes(basicMetadataTypes);
		try {
			
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setMethods(Methods data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		MethodsBD methods = new MethodsBD();
		methods.setMethods(data.getMethods());
		methods.setQualityControl(data.getQualityControl());
		methods.setSamplingDescription(data.getSamplingDescription());
		metaDataBD.setMethods(methods);
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setResearchProject(ResearchProject data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		ResearchProjectBD researchProject = new ResearchProjectBD();
		researchProject.setAbstract1(data.getAbstract1());
		researchProject.setDesignDescription(data.getDesignDescription());
		researchProject.setFunding(data.getFunding());
		researchProject.setLeadOganization(data.getLeadOganization());
		researchProject.setStudyAreaDescription(data.getStudyAreaDescription());
		researchProject.setTitle(data.getTitle());
		metaDataBD.setResearchProject(researchProject);
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setResourceOriginator(ResourceOriginator data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		ResourceOriginatorBD resourceOriginator = new ResourceOriginatorBD();
		resourceOriginator.setAddress(data.getAddress());
		resourceOriginator.setCity(data.getCity());
		resourceOriginator.setCountry(data.getCity());
		resourceOriginator.setEmail(data.getEmail());
		resourceOriginator.setFirstName(data.getFirstName());
		resourceOriginator.setHomepage(data.getHomepage());
		resourceOriginator.setLastName(data.getLastName());
		resourceOriginator.setOrganisation(data.getOrganisation());
		resourceOriginator.setPhone(data.getPhone());
		resourceOriginator.setPostalCode(data.getPostalCode());
		resourceOriginator.setProvince(data.getProvince());
		resourceOriginator.setResourceLanguage(data.getResourceLanguage());
		
		metaDataBD.setResourceOriginator(resourceOriginator);
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setTaxonomicCoverage(TaxonomicCoverage data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		TaxonomicCoverageBD taxonomicCoverage = new TaxonomicCoverageBD();
		taxonomicCoverage.setGeneralDescription(data.getGeneralDescription());
		taxonomicCoverage.setTaxonomicKeywords(data.getTaxonomicKeywords());
		
		
		metaDataBD.setTaxonomicCoverage(taxonomicCoverage);
		
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setTemporalCoverage(TemporalCoverage data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		TemporalCoverageBD temporalCoverage = new TemporalCoverageBD();
		temporalCoverage.setEndDate(data.getEndDate());
		temporalCoverage.setStartDate(data.getStartDate());
		
		metaDataBD.setTemporalCoverage(temporalCoverage);
		
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setGeneralKeywords(GeneralKeywords data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		GeneralKeywordsBD generalKeywords = new GeneralKeywordsBD();
		generalKeywords.setKeywords(data.getKeywords());
		metaDataBD.setGeneralKeywords(generalKeywords);
		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setIPRights(IPRights data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaDataBD metaData = new MetaDataBD();
		metaData = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		
		IPRightBD ipRights = new IPRightBD();
		ipRights.setIpRights(data.getIpRights());
		ipRights.setMaintance(data.getMaintance());
		ipRights.setPurpose(data.getPurpose());
		
		metaData.setIpRights(ipRights);
		try {
			pm.retrieve(metaData);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setGeographicCoverage(GeographicCoverage data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		
		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		GeographicCoverageBD geographicCoverage = new GeographicCoverageBD();
		geographicCoverage.setLatitude(data.getLatitude());
		geographicCoverage.setLongitude(data.getLongitude());
		geographicCoverage.setRadius(data.getRadius());
		metaDataBD.setGeographicCoverage(geographicCoverage);

		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	public String setLowestCommonTax(LowestCommonTax data, String key)
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();

		MetaDataBD metaDataBD = new MetaDataBD();
		metaDataBD = pm.getObjectById(MetaDataBD.class, KeyFactory.stringToKey(key));
		LowestCommonTaxBD lowestCommonTax = new LowestCommonTaxBD();
		lowestCommonTax.setCommontName(data.getCommontName());
		lowestCommonTax.setScientificName(data.getScientificName());
		metaDataBD.setLowestCommonTax(lowestCommonTax);

		try {
			pm.retrieve(metaDataBD);
		} finally {
			pm.close();
		}
		return key;
	}
	
	@SuppressWarnings("null")
	public List<MetaData> getCollections()
	throws IllegalArgumentException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		
		String q ="SELECT FROM " + MetaDataBD.class.getName
		() + " order by title asc";
		
		Query query = pm.newQuery(q);
		query.setRange(1,5);
		List<MetaData> resultsParsed = new ArrayList();

		try {
			List<MetaDataBD> results = (List<MetaDataBD>) query.execute();
			for(MetaDataBD p : results)
				resultsParsed.add(parseMetaData(p));
        	
			
		} 
		catch(NoTableManagedException e){
			
		}
		finally {
			pm.close();
		}
		return resultsParsed;
	}
	
	@Override
	public Boolean login(String userLogin, String userSenha)
			throws IllegalArgumentException {

		if(userLogin.equals("admin")&&userSenha.equals("admin"))
			return true;
		else
			return false;
	}

	

}
